home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / set.h < prev    next >
C/C++ Source or Header  |  1999-10-09  |  16KB  |  673 lines

  1. // $Id: set.h,v 1.8 1999/10/09 15:38:33 shields Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler
  4. // License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #ifndef set_INCLUDED
  11. #define set_INCLUDED
  12.  
  13. #include "config.h"
  14. #include "assert.h"
  15. #include "symbol.h"
  16.  
  17. class ShadowSymbol
  18. {
  19. public:
  20.     ShadowSymbol *next;
  21.     Symbol *symbol;
  22.     int pool_index;
  23.  
  24.     inline NameSymbol *Identity() { return symbol -> Identity(); }
  25.  
  26.     ShadowSymbol(Symbol *symbol_) : symbol(symbol_),
  27.                                     conflict(NULL)
  28.     {}
  29.  
  30.     ~ShadowSymbol() { delete conflict; }
  31.  
  32.     Symbol *Conflict(int i) { return (*conflict)[i]; }
  33.  
  34.     inline int NumConflicts()
  35.     {
  36.         return (conflict ? conflict -> Length() : 0);
  37.     }
  38.  
  39.     inline void AddConflict(Symbol *conflict_symbol)
  40.     {
  41.         if ((symbol != conflict_symbol) && (! Find(conflict_symbol)))
  42.             conflict -> Next() = conflict_symbol;
  43.         return;
  44.     }
  45.  
  46.     inline void RemoveConflict(int k)
  47.     {
  48.         int last_index = conflict -> Length() - 1;
  49.         if (k < 0) // when k is negative, it identifies the main symbol
  50.              symbol = (*conflict)[last_index];
  51.         else (*conflict)[k] = (*conflict)[last_index];
  52.         conflict -> Reset(last_index);
  53.     }
  54.  
  55. private:
  56.     Tuple<Symbol *> *conflict;
  57.  
  58.     bool Find(Symbol *conflict_symbol)
  59.     {
  60.         if (! conflict)
  61.             conflict = new Tuple<Symbol *>(4);
  62.         for (int k = 0; k < conflict -> Length(); k++)
  63.             if ((*conflict)[k] == conflict_symbol)
  64.                 return true;
  65.         return false;
  66.     }
  67. };
  68.  
  69.  
  70. class SymbolSet
  71. {
  72. public:
  73.     enum
  74.     {
  75.         DEFAULT_HASH_SIZE = 13,
  76.         MAX_HASH_SIZE = 1021
  77.     };
  78.  
  79.     SymbolSet(int hash_size_ = DEFAULT_HASH_SIZE) : symbol_pool(256),
  80.                                                     main_index(0),
  81.                                                     sub_index(0)
  82.     {
  83.         hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  84.  
  85.         prime_index = -1;
  86.         do
  87.         {
  88.             if (hash_size < primes[prime_index + 1])
  89.                 break;
  90.             prime_index++;
  91.         } while (primes[prime_index] < MAX_HASH_SIZE);
  92.  
  93.         base = (ShadowSymbol **) memset(new ShadowSymbol *[hash_size], 0, hash_size * sizeof(ShadowSymbol *));
  94.     }
  95.  
  96.     ~SymbolSet();
  97.  
  98.     //
  99.     // Calculate the size of the set an return the value.
  100.     //
  101.     inline int Size()
  102.     {
  103.         int size = 0;
  104.  
  105.         for (int i = 0; i < symbol_pool.Length(); i++)
  106.         {
  107.             ShadowSymbol *shadow = symbol_pool[i];
  108.             Symbol *symbol = shadow -> symbol;
  109.             for (int k = 0; symbol; symbol = (Symbol *) (k < shadow -> NumConflicts() ? shadow -> Conflict(k++) : NULL))
  110.                 size++;
  111.         }
  112.  
  113.         return size;
  114.     }
  115.  
  116.     //
  117.     // Empty out the set in question - i.e., remove all its elements
  118.     //
  119.     inline void SetEmpty()
  120.     {
  121.         for (int i = 0; i < symbol_pool.Length(); i++)
  122.             delete symbol_pool[i];
  123.         symbol_pool.Reset();
  124.         base = (ShadowSymbol **) memset(base, 0, hash_size * sizeof(ShadowSymbol *));
  125.     }
  126.  
  127.     //
  128.     // Empty out the set in question - i.e., remove all its elements
  129.     //
  130.     bool IsEmpty() { return symbol_pool.Length() == 0; }
  131.  
  132.     //
  133.     // Assignment of a set to another.
  134.     //
  135.     SymbolSet &operator=(SymbolSet &rhs)
  136.     {
  137.         if (this != &rhs)
  138.         {
  139.             this -> SetEmpty();
  140.             this -> Union(rhs);
  141.         }
  142.  
  143.         return *this;
  144.     }
  145.  
  146.     //
  147.     // Equality comparison of two sets
  148.     //
  149.     bool operator==(SymbolSet &);
  150.  
  151.     //
  152.     // NonEquality comparison of two sets
  153.     //
  154.     inline bool operator!=(SymbolSet &rhs)
  155.     {
  156.         return ! (*this == rhs);
  157.     }
  158.  
  159.     //
  160.     // Union the set in question with the set passed as argument: "set"
  161.     //
  162.     void Union(SymbolSet &);
  163.  
  164.     //
  165.     // Intersect the set in question with the set passed as argument: "set"
  166.     //
  167.     void Intersection(SymbolSet &);
  168.  
  169.     //
  170.     // Return a bolean value indicating whether or not the set in question intersects the set passed as argument: "set"
  171.     // i.e., is there at least one element of set that is also an element of "this" set.
  172.     //
  173.     bool Intersects(SymbolSet &);
  174.  
  175.     //
  176.     // How many elements with this name symbol do we have?
  177.     //
  178.     inline int NameCount(Symbol *element)
  179.     {
  180.         NameSymbol *name_symbol = element -> Identity();
  181.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  182.         {
  183.             if (shadow -> Identity() == name_symbol)
  184.                 return shadow -> NumConflicts() + 1;
  185.         }
  186.  
  187.         return 0;
  188.     }
  189.  
  190.     //
  191.     // Is "element" an element of the set in question ?
  192.     //
  193.     inline bool IsElement(Symbol *element)
  194.     {
  195.         assert(element);
  196.  
  197.         NameSymbol *name_symbol = element -> Identity();
  198.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  199.         {
  200.             if (shadow -> Identity() == name_symbol)
  201.             {
  202.                 Symbol *symbol = shadow -> symbol;
  203.                 for (int k = 0; symbol; symbol = (Symbol *) (k < shadow -> NumConflicts() ? shadow -> Conflict(k++) : NULL))
  204.                 {
  205.                     if (symbol == element)
  206.                         return true;
  207.                 }
  208.  
  209.                 return false;
  210.             }
  211.         }
  212.  
  213.         return false;
  214.     }
  215.  
  216.     //
  217.     // Add element to the set in question if was not already there.
  218.     //
  219.     inline void AddElement(Symbol *element)
  220.     {
  221.         NameSymbol *name_symbol = element -> Identity();
  222.         int i = name_symbol -> index % hash_size;
  223.  
  224.         ShadowSymbol *shadow;
  225.         for (shadow = base[i]; shadow; shadow = shadow -> next)
  226.         {
  227.             if (shadow -> Identity() == name_symbol)
  228.             {
  229.                 shadow -> AddConflict(element);
  230.                 return;
  231.             }
  232.         }
  233.  
  234.         shadow = new ShadowSymbol(element);
  235.         shadow -> pool_index = symbol_pool.Length();
  236.         symbol_pool.Next() = shadow;
  237.  
  238.         shadow -> next = base[i];
  239.         base[i] = shadow;
  240.  
  241.         //
  242.         // If the set is "adjustable" and the number of unique elements in it exceeds
  243.         // 2 times the size of the base, and we have not yet reached the maximum
  244.         // allowable size for a base, reallocate a larger base and rehash the elements.
  245.         //
  246.         if ((symbol_pool.Length() > (hash_size << 1)) && (hash_size < MAX_HASH_SIZE))
  247.             Rehash();
  248.  
  249.         return;
  250.     }
  251.  
  252.  
  253.     void RemoveElement(Symbol *);
  254.  
  255.     Symbol* FirstElement()
  256.     {
  257.         main_index = 0;
  258.         sub_index = 0;
  259.         return (main_index < symbol_pool.Length() ? symbol_pool[main_index] -> symbol : (Symbol *) NULL);
  260.     }
  261.  
  262.     Symbol* NextElement()
  263.     {
  264.         Symbol *symbol = NULL;
  265.  
  266.         if (main_index < symbol_pool.Length())
  267.         {
  268.              if (sub_index < symbol_pool[main_index] -> NumConflicts())
  269.                   symbol = symbol_pool[main_index] -> Conflict(sub_index++);
  270.              else
  271.              {
  272.                  main_index++;
  273.                  sub_index = 0;
  274.                  symbol = (main_index < symbol_pool.Length() ? symbol_pool[main_index] -> symbol : (Symbol *) NULL);
  275.              }
  276.         }
  277.  
  278.         return symbol;
  279.     }
  280.  
  281. protected:
  282.  
  283.     Tuple<ShadowSymbol *> symbol_pool;
  284.  
  285.     int main_index,
  286.         sub_index;
  287.  
  288.     ShadowSymbol **base;
  289.     int hash_size;
  290.  
  291.     static int primes[];
  292.     int prime_index;
  293.  
  294.     void Rehash();
  295. };
  296.  
  297.  
  298. //
  299. // Single-value Mapping from a name_symbol into a symbol with that name.
  300. //
  301. class NameSymbolMap : public SymbolSet
  302. {
  303. public:
  304.     NameSymbolMap(int hash_size_ = DEFAULT_HASH_SIZE) : SymbolSet(hash_size_)
  305.     {}
  306.  
  307.     //
  308.     // Is there an element with this name in the map ?
  309.     //
  310.     inline Symbol *Image(NameSymbol *name_symbol)
  311.     {
  312.         assert(name_symbol);
  313.  
  314.         for (ShadowSymbol *shadow = base[name_symbol -> index % hash_size]; shadow; shadow = shadow -> next)
  315.         {
  316.             if (shadow -> Identity() == name_symbol)
  317.                 return shadow -> symbol;
  318.         }
  319.  
  320.         return NULL;
  321.     }
  322.  
  323.     //
  324.     // Add element to the set in question if was not already there.
  325.     //
  326.     inline void AddElement(Symbol *element)
  327.     {
  328.         assert(element);
  329.  
  330.         ShadowSymbol *shadow = NULL;
  331.         for (shadow = base[element -> Identity() -> index % hash_size]; shadow; shadow = shadow -> next)
  332.         {
  333.             if (shadow -> Identity() == element -> Identity())
  334.                 break;
  335.         }
  336.  
  337.         //
  338.         // If an element was already mapped into that name, replace it.
  339.         // Otherwise, add the new element.
  340.         //
  341.         if (shadow)
  342.              shadow -> symbol = element;
  343.         else SymbolSet::AddElement(element);
  344.  
  345.         return;
  346.     }
  347. };
  348.  
  349.  
  350. //
  351. // Single-value Mapping from an arbitrary symbol into another arbitrary symbol.
  352. //
  353. class SymbolMap
  354. {
  355. public:
  356.     enum
  357.     {
  358.         DEFAULT_HASH_SIZE = 13,
  359.         MAX_HASH_SIZE = 1021
  360.     };
  361.  
  362.     SymbolMap(int hash_size_ = DEFAULT_HASH_SIZE);
  363.     ~SymbolMap();
  364.  
  365.     //
  366.     // Has symbol been mapped to an image, yet? If so, return the image.
  367.     //
  368.     inline Symbol *Image(Symbol *symbol)
  369.     {
  370.         assert(symbol);
  371.  
  372.         int k = symbol -> Identity() -> index % hash_size;
  373.         for (Element *element = base[k]; element; element = element -> next)
  374.         {
  375.             if (element -> domain_element == symbol)
  376.                 return element -> image;
  377.         }
  378.  
  379.         return NULL;
  380.     }
  381.  
  382.     //
  383.     // Map or remap symbol to a given image.
  384.     //
  385.     void Map(Symbol *, Symbol *);
  386.  
  387. private:
  388.  
  389.     class Element
  390.     {
  391.     public:
  392.         Element *next;
  393.         Symbol  *domain_element,
  394.                 *image;
  395.     };
  396.  
  397.     Tuple<Element *> symbol_pool;
  398.  
  399.     Element **base;
  400.     int hash_size;
  401.  
  402.     static int primes[];
  403.     int prime_index;
  404.  
  405.     void Rehash();
  406. };
  407.  
  408.  
  409. //
  410. // This Bitset template class can be used to construct sets of
  411. // integers. The template takes as argument the address of an integer
  412. // variable, set_size, which indicates that the universe of the sets
  413. // is: {0..*set_size}.
  414. //
  415. class BitSet
  416. {
  417.     typedef unsigned CELL;
  418.  
  419.     CELL *s;
  420.     const int set_size;
  421.  
  422. public:
  423.  
  424.     enum { EMPTY, UNIVERSE, cell_size = sizeof(CELL) * CHAR_BIT };
  425.  
  426.     //
  427.     // Produce the empty set.
  428.     //
  429.     void SetEmpty()
  430.     {
  431.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  432.             s[i] = 0;
  433.     }
  434.  
  435.     //
  436.     // Produce the universe set.
  437.     //
  438.     void SetUniverse()
  439.     {
  440.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  441.             s[i] = ~((CELL) 0);
  442.     }
  443.  
  444.     //
  445.     // This function takes as argument the size of a hash table, table_size.
  446.     // It hashes a bitset into a location within the range <1..table_size-1>.
  447.     //
  448.     int Hash(int table_size)
  449.     {
  450.         unsigned long hash_address = 0;
  451.  
  452.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  453.             hash_address += s[i];
  454.  
  455.         return hash_address % table_size;
  456.     }
  457.  
  458.     //
  459.     // Assignment of a bitset to another.
  460.     //
  461.     BitSet& operator=(const BitSet& rhs)
  462.     {
  463.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  464.             s[i] = rhs.s[i];
  465.  
  466.         return *this;
  467.     }
  468.  
  469.     //
  470.     // Constructor of an uninitialized bitset.
  471.     //
  472.     BitSet(int set_size_) : set_size(set_size_)
  473.     {
  474.         //
  475.         // Note that we comment out the -1 because some C++ compilers
  476.         // do not know how to allocate an array of size 0. Note that
  477.         // we assert that set_size >= 0.
  478.         //
  479.         s = new CELL[(set_size + cell_size /* - 1 */) / cell_size];
  480.     }
  481.  
  482.     //
  483.     // Constructor of an initialized bitset.
  484.     //
  485.     BitSet(int set_size_, int init) : set_size(set_size_)
  486.     {
  487.         //
  488.         // Note that we comment out the -1 because some C++ compilers
  489.         // do not know how to allocate an array of size 0. Note that
  490.         // we assert that set_size >= 0.
  491.         //
  492.         s = new CELL[(set_size + cell_size /* - 1 */) / cell_size];
  493.         if (init == UNIVERSE)
  494.              SetUniverse();
  495.         else SetEmpty();
  496.     }
  497.  
  498.     //
  499.     // Constructor to clone a bitset.
  500.     //
  501.     BitSet(const BitSet& rhs) : set_size(rhs.set_size)
  502.     {
  503.         //
  504.         // Note that we comment out the -1 because some C++ compilers
  505.         // do not know how to allocate an array of size 0. Note that
  506.         // we assert that set_size >= 0.
  507.         //
  508.         s = new CELL[(set_size + cell_size /* - 1 */) / cell_size];
  509.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  510.             s[i] = rhs.s[i];
  511.     }
  512.  
  513.     //
  514.     // Destructor of a bitset.
  515.     //
  516.     ~BitSet() { delete [] s; }
  517.  
  518.     //
  519.     // Return size of a bit set.
  520.     //
  521.     int Size() { return set_size; }
  522.  
  523.     //
  524.     // Return a boolean value indicating whether or not the element i
  525.     // is in the bitset in question.
  526.     //
  527.     bool operator[](const int i)
  528.     {
  529.         assert(i >= 0 && i < set_size);
  530.  
  531.         return (s[i / cell_size] &
  532.                 ((i + cell_size) % cell_size
  533.                           ? (CELL) 1 << ((i + cell_size) % cell_size)
  534.                           : (CELL) 1)) != 0;
  535.     }
  536.  
  537.     //
  538.     // Insert an element i in the bitset in question.
  539.     //
  540.     void AddElement(int i)
  541.     {
  542.         assert(i >= 0 && i < set_size);
  543.  
  544.         s[i / cell_size] |= ((i + cell_size) % cell_size
  545.                                              ? (CELL) 1 << ((i + cell_size) % cell_size)
  546.                                              : (CELL) 1);
  547.     }
  548.  
  549.     //
  550.     // Remove an element i from the bitset in question.
  551.     //
  552.     void RemoveElement(int i)
  553.     {
  554.         assert(i >= 0 && i < set_size);
  555.  
  556.         s[i / cell_size] &= ~((i + cell_size) % cell_size
  557.                                               ? (CELL) 1 << ((i + cell_size) % cell_size)
  558.                                               : (CELL) 1);
  559.     }
  560.  
  561.     //
  562.     // Yield a boolean result indicating whether or not two sets are
  563.     // identical.
  564.     //
  565.     int operator==(const BitSet& rhs)
  566.     {
  567.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  568.         {
  569.             if (s[i] != rhs.s[i])
  570.                 return 0;
  571.         }
  572.  
  573.         return 1;
  574.     }
  575.  
  576.     //
  577.     // Yield a boolean result indicating whether or not two sets are
  578.     // identical.
  579.     //
  580.     int operator!=(const BitSet& rhs)
  581.     {
  582.         return ! (*this == rhs);
  583.     }
  584.  
  585.     //
  586.     // Union of two bitsets.
  587.     //
  588.     BitSet operator+(const BitSet& rhs)
  589.     {
  590.         BitSet result(set_size);
  591.  
  592.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  593.             result.s[i] = s[i] | rhs.s[i];
  594.  
  595.         return result;
  596.     }
  597.  
  598.     //
  599.     // Union of an lvalue bitset and a rhs bitset.
  600.     //
  601.     BitSet& operator+=(const BitSet& rhs)
  602.     {
  603.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  604.             s[i] |= rhs.s[i];
  605.  
  606.         return *this;
  607.     }
  608.  
  609.     //
  610.     // Intersection of two bitsets.
  611.     //
  612.     BitSet operator*(const BitSet& rhs)
  613.     {
  614.         BitSet result(set_size);
  615.  
  616.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  617.             result.s[i] = s[i] & rhs.s[i];
  618.  
  619.         return result;
  620.     }
  621.  
  622.     //
  623.     // Intersection of an lvalue bitset and a rhs bitset.
  624.     //
  625.     BitSet& operator*=(const BitSet& rhs)
  626.     {
  627.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  628.             s[i] &= rhs.s[i];
  629.  
  630.         return *this;
  631.     }
  632.  
  633.     //
  634.     // Difference of two bitsets.
  635.     //
  636.     BitSet operator-(const BitSet& rhs)
  637.     {
  638.         BitSet result(set_size);
  639.  
  640.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  641.             result.s[i] = s[i] & (~ rhs.s[i]);
  642.  
  643.         return result;
  644.     }
  645.  
  646.     //
  647.     // Difference of an lvalue bitset and a rhs bitset.
  648.     //
  649.     BitSet& operator-=(const BitSet& rhs)
  650.     {
  651.         for (int i = (set_size - 1) / cell_size; i >= 0; i--)
  652.             s[i] &= (~ rhs.s[i]);
  653.  
  654.         return *this;
  655.     }
  656. };
  657.  
  658. class DefiniteAssignmentSet
  659. {
  660. public:
  661.     int set_size;
  662.  
  663.     BitSet true_set,
  664.            false_set;
  665.  
  666.     DefiniteAssignmentSet(int set_size_) : set_size(set_size_),
  667.                                            true_set(set_size),
  668.                                            false_set(set_size)
  669.     {}
  670. };
  671. #endif
  672.  
  673.